/*
 * 精彩绘本抢先看页面编辑
 */
import * as React from 'react';
import { connect } from 'react-redux';
import { get } from 'lodash';

import Media from 'components/common/Media';
import ContentEditable from 'components/common/ContentEditable';
import AudioPlayer from 'components/common/AudioPlayer';

import LoadableComponent from 'components/common/LoadableComponent';
const LoadableSentenceEdit = LoadableComponent(() => import('components/common/EditSentence'));
const LoadableDragger = LoadableComponent(() => import('components/common/Dragger'));

import './Page.scss';
import { createPage, savePage, fetchPageDetail } from 'actions/preview';

import { Card, Popconfirm, Checkbox, Tooltip, Spin, Icon, Button, message } from 'antd';

interface PageEditProps {
  dispatch: (action: any) => any;
  newPageCallback: (newPageId?: number) => any;
  loadingGroup: any;
  previewId: number;
  pageId: number;
}
interface PageEditState {
  editSentence: any;
  editSentenceIndex: number;
  editPage: any;
}

class PageEdit extends React.Component<PageEditProps, PageEditState> {
  static defaultProps: PageEditProps = {
    dispatch: () => {},
    newPageCallback: () => {},
    pageId: 0,
    previewId: 0,
    loadingGroup: {},
  };

  constructor(props: PageEditProps) {
    super(props);
    this.state = {
      editSentence: null,
      editSentenceIndex: -1,
      editPage: null,
    };
  }

  componentDidMount() {
    if (this.props.pageId) {
      this.handleFetchPageDetail();
    }
  }

  componentWillReceiveProps(nextProps: any) {
    const { pageId } = nextProps;
    const { pageId: oldPageId } = this.props;

    if (pageId !== oldPageId) {
      if (pageId) {
        this.handleFetchPageDetail(pageId);
      } else {
        this.setState({
          editPage: null,
        });
      }
    }
  }

  handleFetchPageDetail = (pageId: number = this.props.pageId) => {
    const { dispatch, previewId } = this.props;

    dispatch(fetchPageDetail(previewId, pageId)).then((result: any) => {
      if (result.code) {
        message.error(result.msg);
      } else {
        this.setState({
          editPage: result.response.data,
        });
      }
    });
  };

  onCloseEditor = () => {
    this.setState({
      editSentence: null,
    });
  };

  onOpenEditor = (editSentence: any = 0, editSentenceIndex: number = -1) => {
    this.setState({
      editSentence,
      editSentenceIndex,
    });
  };

  handleSavePage = (data: Record<string, any>, callback = () => {}) => {
    const { dispatch, previewId, pageId, newPageCallback } = this.props;

    const action = pageId ? savePage(previewId, pageId, data) : createPage(previewId, data);

    dispatch(action).then((result: any) => {
      if (result.code) {
        message.error(result.msg);
      } else {
        message.success('保存成功');
        if (!pageId) {
          newPageCallback(result.response.data);
        } else {
          this.handleFetchPageDetail();
        }
        callback();
      }
    });
  };

  handleRemoveMedia = (mediaId?: number) => {
    let { content } = this.state.editPage;
    const { attachment, ...other } = content;
    content = { ...other };
    this.handleSavePage({ content });
  };

  handleUploadDone = (response: any) => {
    const attachment = response.files[0];
    let content = get(this.state.editPage, 'content', null);
    content = { ...content, attachment };
    this.handleSavePage({ content });
  };

  handleRemoveSentence(sentenceIndex: number) {
    let { content } = this.state.editPage;
    const { sentences, ...other } = content;
    sentences.splice(sentenceIndex, 1);
    content = { sentences, ...other };

    this.handleSavePage({ content });
  }

  handleSaveSentence = (data: Record<string, any>) => {
    const { editPage, editSentenceIndex } = this.state;
    let content = get(editPage, 'content', null);
    let sentences = get(content, 'sentences', []);

    const { audio, sentence, words } = data;

    let item: any = {
      sentence,
      words,
    };
    if (audio) {
      item = { ...item, audio };
    }

    if (editSentenceIndex === -1) {
      // new sentence
      sentences.push(item);
    } else {
      // edit sentence
      sentences[editSentenceIndex] = item;
    }
    content = { ...content, sentences };

    this.handleSavePage({ content }, () => {
      this.onCloseEditor();
    });
  };

  // 名字不需要组装到content里面
  // 注意更新page列表名称
  handleSaveName = (name: string) => {
    const { pageId, newPageCallback } = this.props;
    let data: any = { name };
    const content = get(this.state.editPage, 'content', null);
    if (content) {
      data = { ...data, content };
    }

    this.handleSavePage(data, () => {
      if (pageId) {
        newPageCallback(pageId);
      }
    });
  };

  renderToolbar() {
    return (
      <div className="parser-name text-left">
        <h4 className="parser-name-text">
          <ContentEditable tip="编辑此页面名称" onChange={this.handleSaveName}>
            {get(this.state.editPage, 'name', '')}
          </ContentEditable>
        </h4>
        <hr style={{ color: '#DCE8F1' }} />
      </div>
    );
  }

  renderAttachmentUploader() {
    const attachment = get(this.state.editPage, 'content.attachment', null);
    if (attachment) {
      return null;
    }

    return (
      <div className="attachment-upload">
        <LoadableDragger selectMax={1} accept="image" onDone={this.handleUploadDone}>
          <Button type="primary">
            <Icon type="picture" />
          </Button>
        </LoadableDragger>
      </div>
    );
  }

  renderTitle() {
    return (
      <div>
        <h4 className="text-left parser-sub-title">上传图片</h4>
        {this.renderAttachmentUploader()}
      </div>
    );
  }

  renderMedia() {
    const attachment = get(this.state.editPage, 'content.attachment', null);
    return (
      <Media
        attachment={attachment}
        onDestroy={this.handleRemoveMedia}
        imageStyle={{ width: '50%' }}
      />
    );
  }

  ConfirmToDelete(props: any) {
    return (
      <Popconfirm
        okText="确定"
        cancelText="取消"
        title="你确定要删除此脚本吗？"
        onConfirm={props.onRemove}>
        <Icon type="close" />
      </Popconfirm>
    );
  }

  renderSentenceList() {
    const sentences = get(this.state.editPage, 'content.sentences', []);

    if (sentences.length === 0) {
      return (
        <p className="loading-placeholder">
          还没有数据，&nbsp;
          <a
            href="javascript:void(0);"
            onClick={() => {
              this.onOpenEditor();
            }}>
            <Icon type="plus" />添加
          </a>
        </p>
      );
    }

    return (
      <div>
        {sentences.map((item: any, index: number) => {
          let desc = item.sentence.replace(/-/g, ' ');
          // 多行的换行显示
          desc = desc.replace(/\n/g, '<br />');
          // 关联知识点的做下标记
          item.words.map((word: any) => {
            if (word.knowledgeId) {
              const span = `<span style='border-bottom: 2px dashed #aaa'>${word.name}</span>`;
              desc = desc.replace(word.name, span);
            }
          });
          const descHtml = (
            <div style={{ textAlign: 'left' }} dangerouslySetInnerHTML={{ __html: desc }} />
          );

          const actions = [
            <Icon
              key={index}
              type="edit"
              onClick={e => {
                e.stopPropagation();
                this.onOpenEditor(item, index);
              }}
            />,
            <this.ConfirmToDelete
              key={index}
              onRemove={this.handleRemoveSentence.bind(this, index)}
            />,
          ];
          const avatar =
            item.audio !== undefined ? (
              <AudioPlayer isTiny={true} audioUri={item.audio.uri} />
            ) : null;
          return (
            <Card key={index} style={{ width: '100%', marginBottom: 12 }} actions={actions}>
              <Card.Meta
                avatar={avatar}
                description={descHtml}
                style={{ display: 'flex', alignItems: 'center' }}
              />
            </Card>
          );
        })}
      </div>
    );
  }

  renderSentence() {
    let { editSentence } = this.state;
    const sentences = get(this.state.editPage, 'content.sentences', []);

    return (
      <div>
        <h4 className="text-left parser-sub-title">
          讲解句子&nbsp;&nbsp;
          <Tooltip key="add script" title="添加讲解">
            <Button
              disabled={sentences.length > 0}
              shape="circle"
              type="primary"
              icon="plus"
              onClick={() => {
                this.onOpenEditor();
              }}
            />
          </Tooltip>
        </h4>
        {editSentence !== null && (
          <LoadableSentenceEdit
            editSentence={editSentence}
            onCancel={this.onCloseEditor}
            needEditWords={true}
            onOk={this.handleSaveSentence}
          />
        )}
        {this.renderSentenceList()}
      </div>
    );
  }

  render() {
    return (
      <div className="page-content">
        <Spin spinning={false}>
          <div className="text-center">
            {this.renderToolbar()}
            {this.renderTitle()}
            {this.renderMedia()}
            {this.renderSentence()}
          </div>
        </Spin>
      </div>
    );
  }
}

interface OwnProps {
  previewId: number;
  pageId: number;
  newPageCallback: (newPageId?: number) => any;
}

function mapStateToProps(state: any, ownProps: OwnProps) {
  let { previewId, pageId, newPageCallback } = ownProps;
  const { loadingGroup } = state;

  return {
    pageId,
    previewId,
    loadingGroup,
    newPageCallback,
  };
}

export default connect(mapStateToProps)(PageEdit);
